#!/usr/bin/env python
# -*-coding:utf-8 -*-
__author__ = 'whisky'
__date__ = '2019/2/12 19:24'

from ansible.parsing.dataloader import DataLoader  # 读取yml、json格式的文件
from ansible.vars.manager import VariableManager  # 存储变量信息
from ansible.inventory.manager import InventoryManager  # 用于导入inventory文件
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase
from collections import namedtuple  # 传入的参数可索引，返回一个类

loader = DataLoader()
inventory = InventoryManager(loader=loader, sources=['hosts'])
variable_manager = VariableManager(loader=loader, inventory=inventory)

# groups = inventory.get_groups_dict()

Options = namedtuple('Options',
                     ['connection',
                      'remote_user',
                      'ask_sudo_pass',
                      'verbosity',
                      'ack_pass',
                      'module_path',
                      'forks',
                      'become',
                      'become_method',
                      'become_user',
                      'check',
                      'listhosts',
                      'listtasks',
                      'listtags',
                      'syntax',
                      'sudo_user',
                      'sudo',
                      'diff'])

options = Options(connection='smart',
                  remote_user=None,
                  ack_pass=None,
                  sudo_user=None,
                  forks=5,
                  sudo=None,
                  ask_sudo_pass=False,
                  verbosity=5,
                  module_path=None,
                  become=None,
                  become_method=None,
                  become_user=None,
                  check=False,
                  diff=False,
                  listhosts=None,
                  listtasks=None,
                  listtags=None,
                  syntax=None)

# Play 执行对象和模块
play_source = dict(
    name="Ansible Play ad-hoc test",
    hosts='192.168.1.119',
    gather_facts='no',
    tasks=[
        dict(action=dict(module='shell', args='yum -y install tree')),
        # dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
    ]
)
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)


class ModelResultsCollector(CallbackBase):
    """
    重写callbackBase类的部分方法
    """

    def __init__(self, *args, **kwargs):
        super(ModelResultsCollector, self).__init__(*args, **kwargs)
        self.host_ok = {}
        self.host_unreachable = {}
        self.host_failed = {}

    def v2_runner_on_unreachable(self, result):
        self.host_unreachable[result._host.get_name()] = result

    def v2_runner_on_ok(self, result):
        self.host_ok[result._host.get_name()] = result

    def v2_runner_on_failed(self, result, ignore_errors=False):
        self.host_failed[result._host.get_name()] = result


callback = ModelResultsCollector()

passwords = dict()
tqm = TaskQueueManager(
    inventory=inventory,
    variable_manager=variable_manager,
    loader=loader,
    options=options,
    passwords=passwords,
    stdout_callback=callback,
)
result = tqm.run(play)

print callback.host_ok.items()
# [(u'192.168.1.119', <ansible.executor.task_result.TaskResult object at 0x7fd203df5d90>)]

result_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
for host, result in callback.host_ok.items():
    result_raw['success'][host] = result._result

for host, result in callback.host_failed.items():
    result_raw['failed'][host] = result._result

print result_raw